package com.hm.health.handler;

import android.app.ProgressDialog;
import android.content.Context;

import androidx.appcompat.app.AlertDialog;

import com.goodix.RxProgressDialog.RxProgressSubscribe;
import com.goodix.comsdk.HBDOption;
import com.goodix.comsdk.sdk.IHBDClient;
import com.goodix.http.FirmwareDownloadSubscribe;
import com.goodix.ini.HbdOptionIni;
import com.goodix.ini.IniFileUtils;
import com.goodix.utils.ToastUtils;
import com.goodix.widget.AlertDialogEx;
import com.hm.health.MyApplication;
import com.hm.health.R;
import com.hm.health.Utils.FirmwareOtaUpdateSubscribe;

import java.io.File;
import java.util.Arrays;

import rx.Emitter;
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * 固件升级
 */
public class FirmwareUpdateHandler {

    private Context mContext;
    private IHBDClient mIHBDClient;
    private Subscription mSubscription;

    public FirmwareUpdateHandler(Context context, IHBDClient IHBDClient) {
        mContext = context;
        mIHBDClient = IHBDClient;
    }

    /**
     * 开始固件升级
     */
    public void startUpgrade(boolean showUI) {
        HbdOptionIni hbdOptionIni = MyApplication.getHbdOptionIni();
        String firmwareUrlPath = hbdOptionIni.getFirmwareFileUrlPath();
        String firmwareFileName = hbdOptionIni.getFirmwareFileName();
        HBDOption option = mIHBDClient.getHBDOption();
        String evkVersion = option.getEvkVersion();

        // 固件名称为空，无需升级
        if (firmwareFileName.isEmpty() || firmwareFileName.contains(evkVersion)) {
            if (!showUI) {
                return;
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
            builder.setTitle(mContext.getString(R.string.firmware_upgrade));
            builder.setMessage(evkVersion + "\n"
                    + mContext.getString(R.string.tips_no_need_upgrad_firmware));
            builder.setCancelable(false);
            builder.setPositiveButton(mContext.getString(R.string.ok), null);
            builder.show();
            return;
        }

        // 固件版本与服务器一致，无需升级
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle(mContext.getString(R.string.firmware_upgrade));
        String sb = "当前版本:\t" + evkVersion + "\n" +
                "目标版本:\t" + firmwareFileName + "\n";
        builder.setMessage(sb);
        builder.setCancelable(false);
        builder.setPositiveButton(mContext.getString(R.string.ok), (dialog, which)
                -> downloadFirmware(firmwareFileName, firmwareUrlPath));
        builder.setNegativeButton(mContext.getString(R.string.cancel), null);
        builder.show();
    }

    /**
     * 取消固件升级
     */
    public void cancel() {
        if (null != mSubscription && (!mSubscription.isUnsubscribed())) {
            mSubscription.unsubscribe();
            mSubscription = null;
        }
    }


    /**
     * 固件下载
     */
    private void downloadFirmware(String firmwareFileName, String firmwareUrlPath) {
        // 判断固件是否已经存在
        String firmwareDir = IniFileUtils.getFirmwareFilePath(mContext);
        File dir = new File(firmwareDir);
        String[] files = dir.list();
        if ((null != files) && (files.length > 0)) {
            if (Arrays.binarySearch(files, firmwareFileName) >= 0) {
                // 固件已经存在，直接升级
                startUpgrade(firmwareDir + firmwareFileName);
                return;
            }
        }

        FirmwareDownloadSubscribe downloadSubscribe
                = new FirmwareDownloadSubscribe(firmwareUrlPath, firmwareDir, firmwareFileName);
        mSubscription = Observable.create(downloadSubscribe)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new RxProgressSubscribe<>(mContext.getString(R.string.download_firmware),
                        mContext, ProgressDialog.STYLE_HORIZONTAL, new Observer<Integer>() {
                    @Override
                    public void onCompleted() {
                        startUpgrade(firmwareDir + firmwareFileName);
                    }

                    @Override
                    public void onError(Throwable e) {
                        AlertDialogEx.Builder builder = new AlertDialogEx.Builder(mContext);
                        builder.setMessage(mContext.getString(R.string.tips_when_failed_download_firmware));
                        builder.setCancelable(false);
                        builder.setPositiveButton(mContext.getString(R.string.ok), null);
                        builder.show();
                    }

                    @Override
                    public void onNext(Integer integer) {

                    }
                }));
    }

    /**
     * 固件升级
     * @param firmwarePath 固件文件路径
     */
    private void startUpgrade(String firmwarePath) {
        mSubscription = Observable.create(new FirmwareOtaUpdateSubscribe(mContext, firmwarePath))
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new RxProgressSubscribe<>(mContext.getString(R.string.firmware_upgrade),
                        mContext, ProgressDialog.STYLE_HORIZONTAL, new Observer<Integer>() {
                    @Override
                    public void onCompleted() {
                        ToastUtils.showLongToastMessage(mContext, mContext.getString(R.string.finished_upgrade_firmware));
                         reconnectDevice();
                    }

                    @Override
                    public void onError(Throwable e) {
                        AlertDialogEx.Builder builder = new AlertDialogEx.Builder(mContext);
                        builder.setMessage(mContext.getString(R.string.failed_upgrade_firmware)
                                + "\n" + e.getMessage());
                        builder.setCancelable(false);
                        builder.setPositiveButton(mContext.getString(R.string.ok), null);
                        builder.show();
                    }

                    @Override
                    public void onNext(Integer integer) {

                    }
                }));
    }

    private void reconnectDevice() {
        mIHBDClient.disconnect();
        Observable.create((Action1<Emitter<Integer>>) emitter -> {
            try {
                for (int i = 0; i < 10; ++i) {
                    Thread.sleep(1000);
                    emitter.onNext(i * 10);
                }
            } catch (InterruptedException e) {
                emitter.onError(e);
            }
            emitter.onCompleted();
        }, Emitter.BackpressureMode.BUFFER)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new RxProgressSubscribe<Integer>(
                        mContext.getString(R.string.wait_for_restart_device), mContext,
                        ProgressDialog.STYLE_HORIZONTAL, new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {
                        mIHBDClient.connect(mIHBDClient.getRomaDevice());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                    }
                }));
    }
}
